package com.kakarote.examine.service;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.kakarote.core.common.Const;
import com.kakarote.core.common.enums.FieldEnum;
import com.kakarote.core.feign.admin.service.AdminFileService;
import com.kakarote.core.feign.crm.entity.ExamineField;
import com.kakarote.core.feign.examine.entity.ExamineFlowFieldUpdateLogBO;
import com.kakarote.core.feign.examine.entity.ExamineUpdateFieldBO;
import com.kakarote.core.servlet.ApplicationContextHolder;
import com.kakarote.core.utils.BaseUtil;
import com.kakarote.core.utils.SeparatorUtil;
import com.kakarote.core.utils.UserCacheUtil;
import com.kakarote.examine.entity.PO.ExamineFlowAuthField;
import com.kakarote.examine.entity.PO.ExamineFlowFieldUpdateLog;
import org.apache.ibatis.annotations.Param;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public interface ExamineModuleService {

    /**
     * 查询审批可用的字段
     *
     * @param label      label
     * @param categoryId categoryId
     * @return data
     */
    public List<ExamineField> queryExamineField(Integer label, Long categoryId);

    /**
     * 修改审核状态
     *
     * @param label       类型
     * @param typeId      对应类型主键ID
     * @param checkStatus 审核状态 0待审核、1通过、2拒绝、3审核中 4:撤回 5 未提交 6 创建 7 已删除 8 作废
     * @param data        额外数据
     */
    public void updateCheckStatus(Integer label, Long typeId, Integer checkStatus, Object data);

    /**
     * 校验当前状态是否可以进行，不可进行直接抛异常即可
     *
     * @param label          类型
     * @param typeId         对应类型ID
     * @param checkStatus    审核状态
     * @param oldCheckStatus 之前的审核状态
     */
    public void checkStatus(Integer label, Long typeId, Integer checkStatus, Integer oldCheckStatus);

    /**
     * 获取条件审核需要的数据entity
     *
     * @param label  类型
     * @param typeId 对应类型ID
     * @return map
     */
    public Map<String, Object> getConditionMap(Integer label, Long typeId, Long recordId);

    /**
     * 获取成员组件需要的数据entity
     *
     * @return
     */
    Map<String, Object> getMemberComponentMap(String fieldName, Integer label, Long typeId, Long recordId);

    /**
     * 查看审批授权字段信息
     *
     * @param authFields
     * @param label
     * @param typeId
     * @param fieldUpdateLogs
     * @return
     */
    default List<?> getAuthField(List<ExamineFlowAuthField> authFields, Integer label, Long typeId, List<ExamineFlowFieldUpdateLog> fieldUpdateLogs) {
        return new ArrayList<>();
    }


    default void updateFieldInfo(ExamineUpdateFieldBO examineUpdateFieldBO) {

    }

    default List<Map<String, Object>> queryExamineUpdateLog(List<ExamineFlowFieldUpdateLogBO> list) {
        return new ArrayList<>();
    }

    default Object convertValueByFormType(@Param("value") Object value, @Param("type") Integer type) {
        Object newValue;
        FieldEnum fieldEnum = FieldEnum.parse(type);

        if (ObjectUtil.isEmpty(value)) {
            return value;
        }
        switch (fieldEnum) {
            case USER:
                newValue = UserCacheUtil.getSimpleUsers((SeparatorUtil.toLongSet(value.toString())));
                break;
            case STRUCTURE:
                newValue = UserCacheUtil.getDeptList(SeparatorUtil.toLongSet(value.toString()));
                break;
            case FILE:
                newValue = ApplicationContextHolder.getBean(AdminFileService.class).queryFileList(value.toString()).getData();
                break;
            case HANDWRITING_SIGN:
                newValue = value.toString();
                break;
            case SINGLE_USER:
                newValue = UserCacheUtil.getSimpleUser((Long) value);
                break;
            case AREA:
            case CURRENT_POSITION:
            case AREA_POSITION:
                String valueStr = Optional.ofNullable(value).orElse("").toString();
                newValue = JSON.parse(valueStr);
                break;
            case DATE_INTERVAL:
                String dateIntervalStr = Optional.ofNullable(value).orElse("").toString();
                newValue = StrUtil.split(dateIntervalStr, Const.SEPARATOR);
                break;
            case CUSTOMER:
                newValue = new ArrayList<>();
                break;
            case CONTRACT:
                newValue = new ArrayList<>();
                break;
            default:
                if (BaseUtil.isJSON(value.toString())) {
                    if (BaseUtil.isJSONArray(value.toString())) {
                        newValue = JSONUtil.parseArray(value.toString());
                    } else {
                        newValue = JSONUtil.parseObj(value.toString());
                    }
                } else {
                    newValue = value;
                }
                break;

        }
        return newValue;
    }


    /**
     * 处理明细表格
     *
     * @param datum
     * @param authFieldFieldExtendList
     */
    default void disposeDetailTable(Map<String, Object> datum, List<ExamineFlowAuthField> authFieldFieldExtendList) {
        Object value = datum.get("value");
        List<Map<String, Object>> fieldExtendList = (List<Map<String, Object>>) datum.get("fieldExtendList");

        List<Map<String, Object>> extendList = new ArrayList<>();
        List<String> fieldNames = new ArrayList<>();
        Map<String, ExamineFlowAuthField> authFieldMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(authFieldFieldExtendList)) {
            //不可查看的字段
            fieldNames = authFieldFieldExtendList.stream().filter(e -> e.getAuthLevel() == 1).map(e -> StrUtil.toCamelCase(e.getFieldName())).collect(Collectors.toList());
            authFieldMap = authFieldFieldExtendList.stream().collect(Collectors.toMap(
                    ExamineFlowAuthField::getFieldName, Function.identity(), (k1, k2) -> k1
            ));
        }
        for (Map<String, Object> fieldExtend : fieldExtendList) {
            Object fieldName = fieldExtend.get("fieldName");
            fieldExtend.put("authLevel", 2);
            if (authFieldMap.containsKey(fieldName)) {
                ExamineFlowAuthField examineFlowAuthField = authFieldMap.get(fieldName);
                fieldExtend.put("authLevel", examineFlowAuthField.getAuthLevel());
            }
            if (!fieldNames.contains(StrUtil.toCamelCase(fieldExtend.get("fieldName").toString()))) {
                extendList.add(fieldExtend);
            }
        }
        datum.put("fieldExtendList", extendList);

        List<String> finalFieldNames = fieldNames;
        if (ObjectUtil.isNotEmpty(value)) {
            JSONArray newValues = new JSONArray();
            //避免类型转换异常
            JSONArray objects = JSONUtil.parseArray(value);
            for (Object object : objects) {
                if (BaseUtil.isJSONArray(object.toString())) {
                    JSONArray jsonArray = JSONUtil.parseArray(object.toString());
                    jsonArray.removeIf(o ->
                            finalFieldNames.contains(StrUtil.toCamelCase(JSONUtil.parseObj(o).get("fieldName").toString()))
                    );
                    newValues.add(jsonArray);
                } else {
                    JSONObject jsonObject = JSONUtil.parseObj(object.toString(), false);

                    for (String key : finalFieldNames) {
                        jsonObject.remove(key);
                    }
                    newValues.add(jsonObject);
                }
            }
            datum.put("value", newValues);
        } else {
            datum.put("value", value);
        }
    }



}
